<template>
  <div class="apply-table">
    <filter-table v-if="header" :option="filterOption" :showBtn="addBtn" @handle-filter="handleFilter" @handle-add="handleAdd" />
    <el-alert v-if="subTitle" :title="subTitle" type="error"></el-alert>
    <avue-crud :page="pageOption" :option="tableOption" :data="tableData" :table-loading="tableLoading" @current-change="pageTo" @size-change="handleSizeChange">
      <template v-for="item in slotItem" slot-scope="{ row }" :slot="item.prop">
        <el-popover :key="item.prop" v-if="item.image" placement="top-start" popper-class="popover-image" trigger="hover">
          <img :src="row[item.prop]" />
          <div class="review-image" slot="reference">
            <img :src="row[item.prop]" />
          </div>
        </el-popover>
        <slot v-else :data="row[item.prop]" :row="row" :name="`slot-${item.prop}`" />
      </template>

      <template slot="menu" slot-scope="{row}" :row="row">
        <el-button plain v-if="viewBtn" size="small" icon="el-icon-view" @click.stop="handleView(row)">{{btnText.view || '详情'}}</el-button>
        <el-button plain v-if="editBtn" type="primary" size="small" icon="el-icon-edit" @click.stop="handleEdit(row)">{{btnText.edit || '编辑'}}</el-button>
        <slot :row="row" name="applyMenu" />
        <el-button plain v-if="deleteBtn" type="danger" size="small" icon="el-icon-delete" @click.stop="handleDelete(row)">{{btnText.delete || '删除'}}</el-button>
      </template>
    </avue-crud>
  </div>
</template>

<script>
/**
 * 通用列表组件
 */
import FilterTable from "./FilterTable";
import { mapActions, mapState, mapMutations } from "vuex";
import cloumnsOptionMap from "@/const/columns";
import filtersOptionMap from "@/const/filters";
import ActionTypes from "@/const/action";

const DEFAULT_TABLE_OPTIONS = {
  refreshBtn: false,
  columnBtn: false,
  addBtn: false,
  maxHeight: 560,
  border: false,
  menuWidth: 350,
  menuAlign: "center",
  align: "center",
  editBtn: false,
  delBtn: false,
  header: false
};

export default {
  props: {
    // action
    action: {
      type: String,
      required: true
    },
    // 是否展示筛选栏
    header: {
      type: Boolean,
      default: true
    },
    // 是否展示添加按钮
    addBtn: {
      type: Boolean,
      default: true
    },
    // 是否展示编辑按钮
    editBtn: {
      type: Boolean,
      default: true
    },
    // 是否展示删除按钮
    deleteBtn: {
      type: Boolean,
      default: true
    },
    // 是否展示预览按钮
    viewBtn: {
      type: Boolean,
      default: true
    },
    // 指定跳转详情的路由，默认为/wel/detail
    detail: {
      type: String
    },
    // 表单信息小标题
    subTitle: {
      type: String
    },
    // 按钮文案
    btnText: {
      type: Object,
      default: () => ({})
    }
  },
  data() {
    return {
      tableOption: {},
      filterOption: [],
      currentId: 0
    };
  },
  created() {
    this.filterOption = filtersOptionMap[this.action] || [];
    this.tableOption = {
      ...DEFAULT_TABLE_OPTIONS,
      column: cloumnsOptionMap[this.action] || []
    };
    this.routerFormDetail
      ? this.GetTableData(this.action)
      : this.CreateTableData(this.action);
    this.setRouterForm(false);
  },
  computed: {
    ...mapState("table", ["tableData", "pageOption", "routerFormDetail"]),
    ...mapState("@@loading", {
      tableLoading: state => state.effects["table/GetTableData"]
    }),
    slotItem() {
      if (this.tableOption.column) {
        return this.tableOption.column.filter(item => item.solt);
      }
      return [];
    }
  },
  methods: {
    ...mapActions("table", [
      "GetTableData",
      "CreateTableData",
      "PromiseDeleteRow"
    ]),
    ...mapMutations({
      setPageOption: "table/SET_PAGE_OPTION",
      setRouterForm: "table/SET_ROUTER_FORM",
      setCurrentData: "table/SET_CURRENT_DATA",
      setFilterData: "table/SET_FILTER_DATA"
    }),
    // 获取详情路由
    createDetailUrl(type = "edit", id = "") {
      if (type === "add") {
        return `${this.detail || "/wel/detail"}?action=${
          this.action
        }&type=${type}`;
      }
      return `${this.detail || "/wel/detail"}?action=${
        this.action
      }&type=${type}&id=${id}`;
    },
    // 翻页
    pageTo(num) {
      this.setPageOption({ currentPage: num });
      this.GetTableData(this.action);
    },
    // 每页展示条数变化
    handleSizeChange(size) {
      this.setPageOption({ pageSize: size });
      this.GetTableData(this.action);
    },
    // 点击预览
    handleView(row) {
      this.setCurrentId(row);
      this.setCurrentData({});
      this.$router.push(this.createDetailUrl("view", this.currentId));
    },
    // 点击编辑
    handleEdit(row) {
      this.setCurrentId(row);
      this.setCurrentData({});
      this.$router.push(this.createDetailUrl("edit", this.currentId));
    },
    // 点击删除
    handleDelete(row) {
      this.$confirm("确认删除吗？", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        this.PromiseDeleteRow({
          action: this.action,
          id: row.id,
          row
        })
          .then(() => {
            this.$message({
              type: "success",
              message: "已成功删除"
            });
          })
          .catch(error => {
            this.$message({
              type: "error",
              message: error.message || String(error)
            });
          });
      });
    },
    // 点击添加
    handleAdd() {
      this.setCurrentData({});
      this.$router.push(this.createDetailUrl("add"));
    },
    // 点击筛选
    handleFilter(data) {
      Object.keys(data).forEach(key => {
        if (data[key] === undefined || data[key] === null || data[key] === "") {
          delete data[key];
        }
      });
      this.setFilterData(data);
      this.setPageOption({ currentPage: 1 });
      this.GetTableData(this.action);
    },
    // 刷新列表
    RefreshData() {
      this.GetTableData(this.action);
    },
    // 设置当前操作行的id
    setCurrentId(row) {
      if (this.action === ActionTypes.ACCOUNT_AUTH) {
        this.currentId = row.userId;
        return;
      }
      this.currentId = row.id;
    }
  },
  components: { FilterTable }
};
</script>
<style lang="scss">
.popover-image {
  & img {
    display: block;
    max-width: 60vw;
    max-height: 60vh;
  }
}
.review-image {
  width: 80px;
  height: 80px;
  overflow: hidden;
  position: relative;
  margin: 0 auto;
  cursor: pointer;
  border: 1px solid #ccc;
  img {
    display: block;
    width: 100%;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
  }
}
</style>

